package com.login.config;

import com.alibaba.fastjson.JSON;
import com.common.result.Result;
import com.login.json.JsonAuthenticationFilter;
import com.login.json.JsonAuthenticationProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author 路亚
 * @version 0.1
 * @className SecurityConfig
 * @description
 * @date 2024/12/12 15:47
 * @since jdk11
 */
@Configuration
@RequiredArgsConstructor
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // json格式数据登录
    @Bean
    public JsonAuthenticationFilter jsonAuthenticationFilter() throws Exception {
        JsonAuthenticationFilter authenticationFilter = new JsonAuthenticationFilter();
        authenticationFilter.setAuthenticationManager(authenticationManagerBean());
        authenticationFilter.setAuthenticationSuccessHandler((request, response, authentication) -> {
            Result result = new Result();
            result.setCode(1);
            result.setMsg("登录成功");
            result.setData(authentication.getPrincipal());
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write(JSON.toJSONString(result));
        });
        authenticationFilter.setAuthenticationFailureHandler((request, response, exception) -> {
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write(JSON.toJSONString(Result.error(exception.getMessage())));
        });
        return authenticationFilter;
    }
    private final JsonAuthenticationProvider jsonAuthenticationProvider;


    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.addFilterAt(jsonAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
                .authenticationProvider(jsonAuthenticationProvider);

        http.authorizeRequests()
                .antMatchers("/login/**").permitAll() //放行login下的所有请求
                .anyRequest() //所有请求需要认证才能访问
                .authenticated();

        http.exceptionHandling().authenticationEntryPoint((request, response, e) -> createJSON(response, Result.error("未登录")));

        http.logout().logoutUrl("/logout").logoutSuccessHandler((request, response, authentication) -> createJSON(response, Result.success("退出成功")));

        http.csrf().disable();
    }

    /**
     * 辅助方法，用于创建JSON响应
     *
     * @param response HttpServletResponse对象，用于写入响应
     * @param result   要写入响应的Result对象
     * @throws IOException 写入响应过程中可能抛出的异常
     */
    private void createJSON(HttpServletResponse response, Object result) throws IOException {
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().write(JSON.toJSONString(result));
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
    //        配置放过的静态资源
    //        这里是放行所有静态资源，实际开发中，根据业务来定
        web.ignoring().antMatchers("/css/**", "/js/**", "/images/**");
    }

    /**
     * 配置密码编码器
     *
     * @return 配置好的BCryptPasswordEncoder对象
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
